﻿using System;
using System.Windows;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.Diagnostics;
using MongoDB.Bson;
using MongoDB.Driver;




namespace sqCore
{
    /* Docs:
     * Summary
        * Logger for SqlA System.
        * Allows to write logs to SqlADB/File/Console.
     * Variables
        * ToDB - If true, the logs will write in DB.
        * ToFile - If true, the logs will write in file.
        * FilePath - Path to the logs file.
        * DebugMode - If true, logs that marked as "DebugOnly" will process.
     */
    public static class sqLogger
    {
        public static bool DebugMode = false;
        public static bool ToDB = true;
        public static bool ToFile = false;
        public static string FilePath = ".";


        /* Docs:
         * Summary
            * Write log.
         * Variables
            * LogMessage - Text message.            
            * Params - List of addional info for the log.
            * Param - One addional info for the log. Will add to Params list.
            * calleingData - Data of the class, Function and Thred that write the log.
            * LogID - Unice Id for the log, if any (default: 0).
            * TaskName - If the log belongs to sqTask, contains the Task name.
            * isError - If true, the log will mark as error.
            * debugOnly - If true, the logs will write in file.
            * CreateMessageBox - If true, the logs message will show in MessageBox.
            * isSuccses - If false, the log was not writed successfully.
         */
        public static bool writeLog(string LogMessage = default(string), string TaskName = default(string), string Param = default(string),List<string> Params = default(List<string>), int LogID = default(int), bool isError = false, bool debugOnly = false, bool CreateMessageBox = false)
        {
            
            bool isSuccses = true;
            if (debugOnly && !DebugMode) // if the message marked as debugOnly and DebugMode is false
            {
                isSuccses = true;
                Console.WriteLine(LogMessage); //just write to console
                if (CreateMessageBox) { MessageBox.Show(LogMessage); } //create messageBox if necessary.
                return isSuccses; //and stop.
            }
            BsonDocument calleingData; 
            try
            {
                calleingData = new BsonDocument(){
                {"Classs",new StackFrame(1, true).GetMethod().ReflectedType.Name}, //Caller Class
                {"Method",new StackFrame(1, true).GetMethod().Name}, //Caller Function
                {"Thread",new BsonDocument(){ //Caller Thread data.
                    {"Name",System.Threading.Thread.CurrentThread.Name}, //^
                    {"Id",System.Threading.Thread.CurrentThread.ManagedThreadId}, //^
                    {"IsAlive",System.Threading.Thread.CurrentThread.IsAlive.ToString()} //^
                    }
                },
                {"Caller",new BsonDocument(){
                    {"Classs",new StackFrame(2, true).GetMethod().ReflectedType.Name}, //Caller of caller Class
                    {"Method",new StackFrame(2, true).GetMethod().Name}, //Caller of caller Function
                    }
                }
                };
            }
            catch
            {
                calleingData = new BsonDocument();
                isSuccses = false;
            }
            BsonArray ParamsList = new BsonArray();
            if (Params == default(List<string>))
                Params = new List<string>();
            ParamsList.Add(Param);
            foreach (string p in Params)
                ParamsList.Add(p);
            BsonDocument logData;
            try
            {
                logData = new BsonDocument(){
                {"IsError",isError},
                {"CallingData",calleingData},
                {"TaskName",TaskName},
                {"LogMessage",LogMessage},
                {"LogID",LogID},
                {"Params",ParamsList},
                {"Time",DateTime.Now}, //Add log time.
                };
            }
            catch
            {
                logData = new BsonDocument();
                isSuccses = false;
            }
            if (ToDB)
            {
                try
                {
                    //Connect and Write in SqlADB
                    MongoClient client = new MongoClient();
                    MongoServer server = client.GetServer();
                    MongoDatabase conn = server.GetDatabase("SqlA");
                    MongoCollection<BsonDocument> logs = conn.GetCollection<BsonDocument>("Logs");
                    logs.Insert(logData);
                    Console.WriteLine(LogMessage);
                }
                catch
                {
                    isSuccses = false;
                }
            }
            if (ToFile)
            {
                //Write to file
                FileStream fs;
                fs = new FileStream(@FilePath, FileMode.Append, FileAccess.Write);
                StreamWriter writer = new StreamWriter(fs);
                writer.Write(logData.ToString() + "\n");
                writer.Close();                
            }
            if (CreateMessageBox) { MessageBox.Show(LogMessage); } //create messageBox if necessary.
            return isSuccses; //stop.
        }
    } //end of sqLogger.
}
